using System;
using NFreeMarker.Template;

namespace NFreeMarker.Core
{
    /**
     * @version 1.0
     * @author Attila Szegedi
     */

    internal static class EvaluationUtil
    {
        internal static string GetString(ITemplateScalarModel model, Expression expr, Environment env)
        {
            string value = model.GetAsString();
            if (value == null)
            {
                if (env.IsClassicCompatible())
                {
                    return string.Empty;
                }
                else
                {
                    throw new TemplateException(expr + " evaluated to null string.", env);
                }
            }
            return value;
        }

        internal static Template.Utility.Number GetNumber(Expression expr, Environment env)
        {
            ITemplateModel model = expr.GetAsTemplateModel(env);
            return GetNumber(model, expr, env);
        }

        internal static Template.Utility.Number GetNumber(ITemplateModel model, Expression expr, Environment env)
        {
            if (model is ITemplateNumberModel)
            {
                return GetNumber((ITemplateNumberModel) model, expr, env);
            }
            if (model == null)
            {
                throw new InvalidReferenceException(expr + " is undefined.", env);
            }
            throw new NonNumericalException(expr + " is not a number, it is " + model.GetType().FullName, env);
        }

        internal static Template.Utility.Number GetNumber(ITemplateNumberModel model, Expression expr, Environment env)
        {
            Template.Utility.Number value = model.GetAsNumber();
            if (value == null)
            {
                throw new TemplateException(expr + " evaluated to null number.", env);
            }
            return value;
        }

        internal static DateTimeOffset GetDate(ITemplateDateModel model, Expression expr, Environment env)
        {
            DateTimeOffset value = model.GetAsDate();
            if (value == null)
            {
                throw new TemplateException(expr + " evaluated to null date.", env);
            }
            return value;
        }
    }
}